#======================================================================
# Product:      KnowledgeEngine (Plone Version)
#
# File:         BloggerAPI.py
#
# Copyright:    Copyright (c) 2006, Faulkner Technologies
#
# Author:       John Meredith
#
# Description:  BloggerAPI client.
#======================================================================


#======================================================================
# KnowledgeEngine Imports
#----------------------------------------------------------------------
from AbstractXMLRPCClient import *

#======================================================================
# Zope Library Imports
#----------------------------------------------------------------------


#======================================================================
# Python Library Imports
#----------------------------------------------------------------------
import os
import sys
import unittest
from xmlrpclib import Fault


#======================================================================
# BloggerAPI blog client
#----------------------------------------------------------------------
class BloggerAPI(AbstractXMLRPCClient):
    """
        A blog client that speaks the BloggerAPI. It's probably wise to
        use the AtomAPI if you are talking to Blogspot.com
    """

    # Some meta-data for the blog client
    TITLE = "BloggerAPI (Generic)"

    #---------------------------------------------------------------------------
    # The APPKEY is used by blogger. A unique client APPKEY is no longer
    # required so the following key is provided
    _APPKEY = "0123456789ABCDEF"
    
    #---------------------------------------------------------------------------
    # Flag to identify whether this API allows for anonymous posting to blogs
    ALLOW_ANONYMOUS = False
    

    def isValidConnection(self):
        """
            Returns true if the connection details (ie. username password, server etc)
            given are correct. For the BloggerAPI we can just do a simple user info
            lookup.
        """

        if self.getUserInfo():
            return True

        return False


    def getUsersBlogs(self):
        """
            Returns information on all the blogs a given user is a member of.
        """

        server = self.getServer()

        return server.blogger.getUsersBlogs(self._APPKEY, self.username, self.password)


    def getUserInfo(self):
        """
            Authenticates a user and returns basic user info (name, email, userid, etc.).
        """

        server = self.getServer()

        return server.blogger.getUserInfo(self._APPKEY, self.username, self.password)


    def getPost(self, postId):
        """
            Gets a post by postId
        """

        server = self.getServer()

        return server.blogger.getPost(self._APPKEY, str(postId), self.username, self.password)


    def getRecentPosts(self, blogId, numPosts):
        """
            Returns a list, surprisingly, of all the recent posts
        """

        server = self.getServer()
        
        return server.blogger.getRecentPosts(self._APPKEY, str(blogId), self.username, self.password, int(numPosts))


    def createPost(self, **args):
        """
            Makes a new post to a designated blog. Optionally, will publish the blog after making the post.
        """

        # Setup default newPost parameters
        config = {
            'publish' : True
        }
        config.update(args)

        # If we don't have a blogId, try and find it
        if not config.has_key('blogId') or not config['blogId']:
            # Use the first blog we find as a default
            userBlogsList = self.getUsersBlogs()
            config['blogID'] = userBlogsList[0]['blogid']


        # Check that we have some content
        if not config.has_key('content') and not config['content']:
            raise TypeError, "A blog post must contain some form of content/body text."

        # Create our post
        post = {}
        post['content'] = config['content']

        # Flatten the post dictionary to a single string
        content = ""
        for item in post.values():
            content = content + item

        # If we have a title, let's try and include it
        if config.has_key('title') and config['title']:
            # content = "<title>%s</title>%s" % (config['title'], content, )
            content = "%s\n%s" % (config['title'], content, )

        # Now do the magic to create our post
        server = self.getServer()
        postId = server.blogger.newPost(
            self._APPKEY,
            str(config['blogId']),
            str(self.username),
            str(self.password),
            str(content),
            bool(config['publish'])
        )

        return postId


    def editPost(self, postId, **args):
        """
            Edits a given post. Optionally, will publish the blog after making the edit.
        """

        # Setup default newPost parameters
        config = {
            'publish' : True
        }
        config.update(args)

        # Check we've been given a post ID
        if not postId:
            raise TypeError, 'Must specify the ID of the post you wish to edit'

        # Check that we have some content
        if not config.has_key('content') and not config['content']:
            raise TypeError, "A blog post must contain some form of content/body text."

        content = config['content']

        # Some blogs can take a category as well
        if config.has_key('category') and config['category']:
            category = "<category>%s</category>" % str(config['category'])
            content = category + content

        # If we have a title, wrap it and add to content
        if config.has_key('title') and config['title']:
            title = "<title>%s</title" % str(config['title'])
            content = title + content

        # Now do the magic to create our post
        server = self.getServer()
        
        postId = server.blogger.editPost(
            self._APPKEY,
            str(postId),
            str(self.username),
            str(self.password),
            str(content),
            bool(config['publish'])
        )

        return postId
        

    def deletePost(self, postId, publish=True):
        """
            Remove a post from the blog by postId
        """

        server = self.getServer()
        
        response = server.blogger.deletePost(self._APPKEY, str(postId), self.username, self.password, bool(publish))
        
        return response


#======================================================================
# Register Blog client with the action
#----------------------------------------------------------------------
from Products.KnowledgeEngine.Actions.BlogPost.Clients import registerBlogClient
registerBlogClient(BloggerAPI)
